import { MinusCircleFilled, PlusCircleFilled } from "@ant-design/icons";
import { Button, Divider, Form, Input, List, Modal, Select, Space, message } from "antd";
import { useEffect, useState } from "react";
import { v4 as uuidv4 } from 'uuid';
import { getConnectionApi, getToken } from "../utils/client";
import { getMinAppInfo } from "@linksaas-minapp/api";
import type { MongoServerInfo } from "@linksaas-minapp/api/extra_info";

export interface ConnModalProps {
    onCancel: () => void;
    onOk: (id: string, name: string, hosts: string[]) => void;
}

interface Host {
    id: string;
    addr: string;
}

function ConnModal(props: ConnModalProps) {
    const [name, setName] = useState("");
    const [hosts, setHosts] = useState<Host[]>([
        {
            id: uuidv4(),
            addr: "",
        }
    ]);
    const [defaultDb, setDefaultDb] = useState("");
    const [username, setUsername] = useState("");
    const [password, setPassword] = useState("");
    const [authSource, setAuthSource] = useState("admin");
    const [authMechanism, setAuthMechanism] = useState("SCRAM-SHA-256");
    const [replicaSet, setReplicaSet] = useState("");

    const isValid = () => {
        if (name.trim() == "") {
            return false;
        }
        for (const host of hosts) {
            if (host.addr.trim() == "") {
                return false;
            }
        }
        if (username.trim() == "" && password.trim() !== "") {
            return false;
        } else if (username.trim() !== "" && password.trim() == "") {
            return false;
        }
        return true;
    };

    const addHost = (id: string) => {
        const newList = [] as Host[];
        for (const host of hosts) {
            newList.push(host);
            if (host.id == id) {
                newList.push({
                    id: uuidv4(),
                    addr: "",
                });
            }
        }
        setHosts(newList);
    }

    const connect = async () => {
        let mongoUrl = "mongodb://"
        if (username.trim() !== "" && password.trim() !== "") {
            mongoUrl += `${encodeURIComponent(username.trim())}:${encodeURIComponent(password.trim())}@`;
        }
        mongoUrl += hosts.map(item => item.addr.trim()).join(",");
        mongoUrl += "/";
        mongoUrl += defaultDb;
        const optMap: Map<string, string> = new Map();
        if (authSource.trim() !== "") {
            optMap.set("authSource", authSource.trim());
        }
        optMap.set("authMechanism", authMechanism);
        if (replicaSet.trim() !== "") {
            optMap.set("replicaSet", replicaSet.trim());
        }
        if (optMap.size > 0) {
            mongoUrl += "?";
            for (const [k, v] of optMap.entries()) {
                mongoUrl += `${k}=${encodeURIComponent(v)}&`;
            }
        }
        const client = getConnectionApi();
        try {
            const res = await client.connectionOpenPost({
                connectionOpenPostRequest: {
                    token: getToken(),
                    name: name.trim(),
                    mongoUrl,
                },
            });
            props.onOk(res, name.trim(), hosts.map(item => item.addr));
            message.info("连接成功");
        } catch (e) {
            message.error(`${e}`);
            return;
        }
    };

    useEffect(() => {
        const minAppInfo = getMinAppInfo();
        if (minAppInfo == undefined) {
            return;
        }
        if (minAppInfo.extraInfo != undefined && minAppInfo.extraInfo.length > 0) {
            const serverInfo = JSON.parse(minAppInfo.extraInfo) as MongoServerInfo;
            setName(minAppInfo.extraInfoName ?? "");
            setHosts((serverInfo.addrs ?? []).map(addr => ({
                id: uuidv4(),
                addr: addr,
            })));
            setDefaultDb(serverInfo.defaultDb ?? "");
            setUsername(serverInfo.username ?? "");
            setPassword(serverInfo.password ?? "");
            setAuthSource(serverInfo.authSource ?? "admin");
            setAuthMechanism(serverInfo.authMechanism ?? "SCRAM-SHA-256");
            setReplicaSet(serverInfo.replicaSet ?? "");
        }
    }, []);

    return (
        <Modal open title="连接mongo数据库"
            bodyStyle={{ maxHeight: "calc(100vh - 300px)", overflowY: "auto", paddingRight: "20px" }}
            okText="连接" okButtonProps={{ disabled: !isValid() }}
            onCancel={e => {
                e.stopPropagation();
                e.preventDefault();
                props.onCancel();
            }}
            onOk={e => {
                e.stopPropagation();
                e.preventDefault();
                connect();
            }}>
            <Divider orientation="left">必要参数</Divider>
            <Form labelCol={{ span: 5 }}>
                <Form.Item label="名称">
                    <Input value={name} onChange={e => {
                        e.stopPropagation();
                        e.preventDefault();
                        setName(e.target.value);
                    }} />
                </Form.Item>
                <Form.Item label="连接地址">
                    <List dataSource={hosts} bordered={false} renderItem={item => (
                        <List.Item key={item.id} style={{ padding: "0px 0px 10px 0px", border: "none" }} extra={
                            <Space style={{ marginLeft: "20px" }} size="middle">
                                <Button type="link" style={{ minWidth: 0, padding: "0px 0px" }} onClick={e => {
                                    e.stopPropagation();
                                    e.preventDefault();
                                    addHost(item.id);
                                }}>
                                    <PlusCircleFilled style={{ fontSize: "20px" }} />
                                </Button>
                                <Button type="link" style={{ minWidth: 0, padding: "0px 0px" }} disabled={hosts.length <= 1}
                                    onClick={e => {
                                        e.stopPropagation();
                                        e.preventDefault();
                                        const tmpList = hosts.filter(tmpItem => tmpItem.id != item.id);
                                        setHosts(tmpList);
                                    }}>
                                    <MinusCircleFilled style={{ fontSize: "20px" }} />
                                </Button>
                            </Space>
                        }>
                            <Input value={item.addr} onChange={e => {
                                e.stopPropagation();
                                e.preventDefault();
                                const tmpList = hosts.slice();
                                const index = tmpList.findIndex(tmpItem => tmpItem.id == item.id);
                                if (index != -1) {
                                    tmpList[index].addr = e.target.value;
                                    setHosts(tmpList);
                                }
                            }} />
                        </List.Item>
                    )} />
                </Form.Item>
            </Form>
            <Divider orientation="left">可选参数</Divider>
            <Form labelCol={{ span: 5 }}>
                <Form.Item label="访问数据库" help="当账号无列出数据库权限时，需要制定访问数据库">
                    <Input value={defaultDb} onChange={e => {
                        e.stopPropagation();
                        e.preventDefault();
                        setDefaultDb(e.target.value);
                    }} />
                </Form.Item>
                <Form.Item label="用户名">
                    <Input value={username} onChange={e => {
                        e.stopPropagation();
                        e.preventDefault();
                        setUsername(e.target.value);
                    }} />
                </Form.Item>
                <Form.Item label="密码">
                    <Input.Password value={password} onChange={e => {
                        e.stopPropagation();
                        e.preventDefault();
                        setPassword(e.target.value);
                    }} />
                </Form.Item>
                <Form.Item label="authSource">
                    <Input value={authSource} onChange={e => {
                        e.stopPropagation();
                        e.preventDefault();
                        setAuthSource(e.target.value);
                    }} />
                </Form.Item>
                <Form.Item label="验证机制">
                    <Select value={authMechanism} onChange={value => setAuthMechanism(value)}>
                        <Select.Option value="SCRAM-SHA-1">SCRAM-SHA-1</Select.Option>
                        <Select.Option value="SCRAM-SHA-256">SCRAM-SHA-256</Select.Option>
                    </Select>
                </Form.Item>
                <Form.Item label="replicaSet">
                    <Input value={replicaSet} onChange={e => {
                        e.stopPropagation();
                        e.preventDefault();
                        setReplicaSet(e.target.value);
                    }} />
                </Form.Item>
            </Form>
        </Modal>
    )
}

export default ConnModal;